<?php
class Lead_EDO_Type
{

    private $_fieldsRaw = array();

    private $_tables = array();

    private $_extendedDataTypes = array();

    private $_relations = array();

    private $_relationsClasses = array();

    private $_dimensionalTables = array();
    
    private $_fieldsTables = array();
    
    private $_tablesFields = array();
    
    
    
    public function __construct(Lead_EDO_Object_Abstract $obj)
    {
        $this->_initialize($obj);
    }
    


    private function _initialize(Lead_EDO_Object_Abstract $obj)
    {
        $refle = new ReflectionClass($obj);
        // $statics = $refle->getStaticProperties();

        $relations = array();

        // print "<pre>";
        
        do
        {
            $statics = $refle->getStaticProperties();

            if(isset($statics['_relations'])) {

                // print_r($statics['_relations']);
                
                foreach($statics['_relations'] as $relation) {
                    // $relation['name'] = $key;
                    $this->_relations[$relation['name']] = $relation;
                    $this->_relationsClasses[$relation['name']] = $refle->getName();
                }
            }

            if(isset($statics['_extended_datatypes'])) {
                foreach($statics['_extended_datatypes'] as $key => $value) {
                    $this->_extendedDatatypes[$key] = $value;
                }
            }


            $tables = array_reverse($statics['_tables']);
            foreach($tables as $tablename) {
                if(!in_array($tablename, $this->_tables)) {
                    array_unshift($this->_tables, $tablename);
                 }
            }

            if(isset($statics['_tables_dimensional'])) {
                foreach($statics['_tables_dimensional'] as $dTable) {
                    $this->_tables[] = $dTable;
                    $this->_dimensionalTables[] = $dTable;
                }
            }

            $refle = $refle->getParentClass();

        } while ($refle->getName() != 'Lead_EDO_Object_Abstract');

                       
        
        /*        
        print_r($relations);
        
        die('hih');
        */

        
        $addedTables = $obj->getHandler()->getAddedTables();
        foreach(array_reverse($addedTables) as $addedTable)
            array_unshift($this->_tables, $addedTable);
        

        foreach($this->_tables as $tablekey => $tablename) {
            
            $columns = $obj->getHandler()->db->describeTable($tablename);
    
            $class = get_class($obj->getHandler()->db);
            $columns = call_user_func(array($class, 'nativeToCommon'), $columns);
            
            foreach($columns as $key => &$table_field) {
                $this->_tablesFields[$tablekey][] = $table_field['COLUMN_NAME'];
                $this->_fieldsTables[$table_field['COLUMN_NAME']] = $tablename;
                if(isset($this->_extendedDatatypes[$table_field['COLUMN_NAME']])) {
                    $table_field['DATA_TYPE_EXTENDED'] = $this->_extendedDatatypes[$table_field['COLUMN_NAME']];
                }

                $this->_fieldsRaw[$table_field['COLUMN_NAME']] = $table_field;
            }


        }


    }


    public function getRawFields()
    {
        return $this->_fieldsRaw;
    }

    public function getTables()
    {
        return $this->_tables;
    }


    public function getExtendedDataTypes()
    {
        return $this->_extendedDataTypes;
    }


    public function getRelations()
    {
        return $this->_relations;
    }

    public function getRelationsClasses()
    {
        return $this->_relationsClasses;
    }


    public function getDimensionalTables()
    {
        return $this->_dimensionalTables;
    }


   	public function tableIsDimensional($table)
	{
	    return (in_array($table, $this->getDimensionalTables()));
	}

	public function getRelation($key)
	{

        if(key_exists($key, $this->_relations))
            return $this->_relations[$key];

        throw new Exception("Relation '{$key}' not found.");


	}





	/**
	 * Returns fields tables id.
	 *
	 * @param string $fieldName Field name
	 * @return integer
	 */
	public function getFieldsTableId($fieldName)
	{
	    return array_search($fieldName, $this->getTables());
	}

	/**
	 * Returns fields tables name.
	 *
	 * @param string $fieldName Field name
	 * @return
	 */
	public function getFieldsTable($fieldName)
	{
	    
	    if(isset($this->_fieldsTables[$fieldName]))
	       return $this->_fieldsTables[$fieldName];

	    return false;
	}


	/**
	 * Returns datobjects fields.
	 *
	 * @return array the fields.
	 */
	public function getFields()
	{
		return array_keys($this->_fieldsTables);
	}


	public function getFirstTable()
	{
	    return array_shift($this->getTables());
	}

	public function getRestOfTables()
	{
	    $tables = $this->getTables();
	    array_shift($tables);
	    return $tables;
	}




	/**
	 * Returns fields in a table.
	 *
	 * @param mixed $tableid Tables name or id
	 * @return array
	 */
	public function getTablesFields($tableid)
	{
	    if(!is_numeric($tableid))
		{
			$tableid = $this->tableNameToTableId($tableid);
		}

		return $this->_tablesFields[$tableid];
	}


	/**
	 * Converts table name to table id.
	 *
	 * @param string $tableName Table name
	 * @return integer
	 */
	public function tableNameToTableId($tableName)
	{
		$key = array_search($tableName, $this->getTables());
		return $key;
	}


	public function tableIdToTableName($tableId)
	{
	    $tables = $this->getTables();
	    return $tables[$tableId];

	}


	public function getTable($tableId)
	{
	    throw new Exception('Cant get table its broken');

	    if(is_numeric($tableId))
	    {
	        $tableId = $this->tableIdToTableName($tableId);
	    }

	    $tableObj = $this->db->getTable($tableId);
	    return $tableObj;
	}



	public function getFieldsOfType($dataType)
	{
		$fieldNames = array();

		foreach($this->getFields() as $field)
		{
			$dObject = $this->getFieldObject($field);
			if($dObject->getType() == $dataType)
				$fieldNames[] = $field;
		}
		return $fieldNames;
	}




	/**
	 * Returns dataobjects fields and tables.
	 *
	 * @return array
	 */
	public function getFieldsAndTables()
	{
		return $this->_fieldsTables;
	}


	/**
	 * Returns an assoc array in format 'tablename' => array('field1_name','field2_name')
	 *
	 * @return Array
	 */
	public function getTableFieldNameArray()
	{
		$resultArr = array();
		foreach($this->getTables() as $tbl)
		{
			// $tableid = $this->tableNameToTableId($tbl);
			foreach($this->getFieldsAndTables() as $f => $t_id)
				if($t_id == $tbl)
					$resultArr[$tbl][] = $f;
		}
		return $resultArr;
	}







}

